import 'dart:typed_data';

class MotilityAnalysisResult {
  final double avgTotalDisplacement;
  final double avgVsl;
  final double avgVcl;
  final double avgVap;
  final double avgAlh;
  final int numOfMotileTrajectories;
  final int numOfDetectedSperms;
  final int numOfALevelSperms;
  final int numOfBLevelSperms;
  final int numOfCLevelSperms;
  final Uint8List? imgData;
  final Uint8List? imgDataOfSpermDetection;
  final int createdTime;

  const MotilityAnalysisResult({
    required this.avgTotalDisplacement,
    required this.avgVsl,
    required this.avgVcl,
    required this.avgVap,
    required this.avgAlh,
    required this.numOfMotileTrajectories,
    required this.numOfDetectedSperms,
    required this.numOfALevelSperms,
    required this.numOfBLevelSperms,
    required this.numOfCLevelSperms,
    this.imgData,
    this.imgDataOfSpermDetection,
    required this.createdTime,
  });

  MotilityAnalysisResult copyWith({
    double? avgTotalDisplacement,
    double? avgVsl,
    double? avgVcl,
    double? avgVap,
    double? avgAlh,
    int? numOfMotileTrajectories,
    int? numOfDetectedSperms,
    int? numOfALevelSperms,
    int? numOfBLevelSperms,
    int? numOfCLevelSperms,
    Uint8List? imgData,
    Uint8List? imgDataOfSpermDetection,
    int? createdTime,
  }) {
    return MotilityAnalysisResult(
      avgTotalDisplacement: avgTotalDisplacement ?? this.avgTotalDisplacement,
      avgVsl: avgVsl ?? this.avgVsl,
      avgVcl: avgVcl ?? this.avgVcl,
      avgVap: avgVap ?? this.avgVap,
      avgAlh: avgAlh ?? this.avgAlh,
      numOfMotileTrajectories: numOfMotileTrajectories ?? this.numOfMotileTrajectories,
      numOfDetectedSperms: numOfDetectedSperms ?? this.numOfDetectedSperms,
      numOfALevelSperms: numOfALevelSperms ?? this.numOfALevelSperms,
      numOfBLevelSperms: numOfBLevelSperms ?? this.numOfBLevelSperms,
      numOfCLevelSperms: numOfCLevelSperms ?? this.numOfCLevelSperms,
      imgData: imgData ?? this.imgData,
      imgDataOfSpermDetection: imgDataOfSpermDetection ?? this.imgDataOfSpermDetection,
      createdTime: createdTime ?? this.createdTime,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'avgTotalDisplacement': avgTotalDisplacement,
      'avgVsl': avgVsl,
      'avgVcl': avgVcl,
      'avgVap': avgVap,
      'avgAlh': avgAlh,
      'numOfMotileTrajectories': numOfMotileTrajectories,
      'numOfDetectedSperms': numOfDetectedSperms,
      'numOfALevelSperms': numOfALevelSperms,
      'numOfBLevelSperms': numOfBLevelSperms,
      'numOfCLevelSperms': numOfCLevelSperms,
      'imgData': imgData?.toList(),
      'imgDataOfSpermDetection': imgDataOfSpermDetection?.toList(),
      'createdTime': createdTime,
    };
  }

  factory MotilityAnalysisResult.fromJson(Map<String, dynamic> json) {
    return MotilityAnalysisResult(
      avgTotalDisplacement: json['avgTotalDisplacement']?.toDouble() ?? 0.0,
      avgVsl: json['avgVsl']?.toDouble() ?? 0.0,
      avgVcl: json['avgVcl']?.toDouble() ?? 0.0,
      avgVap: json['avgVap']?.toDouble() ?? 0.0,
      avgAlh: json['avgAlh']?.toDouble() ?? 0.0,
      numOfMotileTrajectories: json['numOfMotileTrajectories']?.toInt() ?? 0,
      numOfDetectedSperms: json['numOfDetectedSperms']?.toInt() ?? 0,
      numOfALevelSperms: json['numOfALevelSperms']?.toInt() ?? 0,
      numOfBLevelSperms: json['numOfBLevelSperms']?.toInt() ?? 0,
      numOfCLevelSperms: json['numOfCLevelSperms']?.toInt() ?? 0,
      imgData: json['imgData'] != null ? Uint8List.fromList(List<int>.from(json['imgData'])) : null,
      imgDataOfSpermDetection: json['imgDataOfSpermDetection'] != null ? Uint8List.fromList(List<int>.from(json['imgDataOfSpermDetection'])) : null,
      createdTime: json['createdTime']?.toInt() ?? 0,
    );
  }

  @override
  String toString() {
    return 'MotilityAnalysisResult(avgTotalDisplacement: $avgTotalDisplacement, avgVsl: $avgVsl, avgVcl: $avgVcl, avgVap: $avgVap, avgAlh: $avgAlh, numOfMotileTrajectories: $numOfMotileTrajectories, numOfDetectedSperms: $numOfDetectedSperms, numOfALevelSperms: $numOfALevelSperms, numOfBLevelSperms: $numOfBLevelSperms, numOfCLevelSperms: $numOfCLevelSperms, imgData: ${imgData != null ? '${imgData!.length} bytes' : 'null'}, imgDataOfSpermDetection: ${imgDataOfSpermDetection != null ? '${imgDataOfSpermDetection!.length} bytes' : 'null'})';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is MotilityAnalysisResult &&
        other.avgTotalDisplacement == avgTotalDisplacement &&
        other.avgVsl == avgVsl &&
        other.avgVcl == avgVcl &&
        other.avgVap == avgVap &&
        other.avgAlh == avgAlh &&
        other.numOfMotileTrajectories == numOfMotileTrajectories &&
        other.numOfDetectedSperms == numOfDetectedSperms &&
        other.numOfALevelSperms == numOfALevelSperms &&
        other.numOfBLevelSperms == numOfBLevelSperms &&
        other.numOfCLevelSperms == numOfCLevelSperms &&
        other.imgData == imgData &&
        other.imgDataOfSpermDetection == imgDataOfSpermDetection;
  }

  @override
  int get hashCode {
    return Object.hash(
      avgTotalDisplacement,
      avgVsl,
      avgVcl,
      avgVap,
      avgAlh,
      numOfMotileTrajectories,
      numOfDetectedSperms,
      numOfALevelSperms,
      numOfBLevelSperms,
      numOfCLevelSperms,
      imgData,
      imgDataOfSpermDetection,
    );
  }
}
